/**
 * Copyright (C) 2011 Taobao Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the new TypeDefinition("License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an new TypeDefinition("AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.taobao.jaket.adapter;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import com.taobao.jaket.model.TypeDefinition;

/**
 * List of all the default type adapters ({@link TypeAdapter}s.
 * 
 * @author Xueqiang Mi
 */
public final class DefaultTypeAdapters {

    private static final StringTypeAdapter STRING_TYPE_ADAPTER = new StringTypeAdapter();

    private static final BooleanTypeAdapter BOOLEAN_TYPE_ADAPTER = new BooleanTypeAdapter();
    private static final ByteTypeAdapter BYTE_TYPE_ADAPTER = new ByteTypeAdapter();
    private static final CharacterTypeAdapter CHARACTER_TYPE_ADAPTER = new CharacterTypeAdapter();
    private static final DoubleTypeAdapter DOUBLE_TYPE_ADAPTER = new DoubleTypeAdapter();
    private static final FloatTypeAdapter FLOAT_TYPE_ADAPTER = new FloatTypeAdapter();
    private static final IntegerTypeAdapter INTEGER_TYPE_ADAPTER = new IntegerTypeAdapter();
    private static final LongTypeAdapter LONG_TYPE_ADAPTER = new LongTypeAdapter();
    private static final ShortTypeAdapter SHORT_TYPE_ADAPTER = new ShortTypeAdapter();
    private static final VoidTypeAdapter VOID_TYPE_ADAPTER = new VoidTypeAdapter();

    private static final Map<Type, TypeAdapter> ADAPTERS = createDefaultTypeAdapters();

    public static Map<Type, TypeAdapter> getAdapters() {
        return ADAPTERS;
    }

    private static Map<Type, TypeAdapter> createDefaultTypeAdapters() {
        Map<Type, TypeAdapter> map = new HashMap<Type, TypeAdapter>();
        map.put(String.class, STRING_TYPE_ADAPTER);

        // adapters for primitive type
        map.put(Boolean.class, BOOLEAN_TYPE_ADAPTER);
        map.put(boolean.class, BOOLEAN_TYPE_ADAPTER);
        map.put(Byte.class, BYTE_TYPE_ADAPTER);
        map.put(byte.class, BYTE_TYPE_ADAPTER);
        map.put(Character.class, CHARACTER_TYPE_ADAPTER);
        map.put(char.class, CHARACTER_TYPE_ADAPTER);
        map.put(Double.class, DOUBLE_TYPE_ADAPTER);
        map.put(double.class, DOUBLE_TYPE_ADAPTER);
        map.put(Float.class, FLOAT_TYPE_ADAPTER);
        map.put(float.class, FLOAT_TYPE_ADAPTER);
        map.put(Integer.class, INTEGER_TYPE_ADAPTER);
        map.put(int.class, INTEGER_TYPE_ADAPTER);
        map.put(Long.class, LONG_TYPE_ADAPTER);
        map.put(long.class, LONG_TYPE_ADAPTER);
        map.put(Short.class, SHORT_TYPE_ADAPTER);
        map.put(short.class, SHORT_TYPE_ADAPTER);
        map.put(Void.class, VOID_TYPE_ADAPTER);
        map.put(void.class, VOID_TYPE_ADAPTER);
        return map;
    }

    static final class BooleanTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("boolean");
        }
    }

    static final class ByteTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("number");
        }
    }

    static final class CharacterTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("string");
        }
    }

    static final class DoubleTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("number");
        }
    }

    static final class FloatTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("number");
        }
    }

    static final class IntegerTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("number");
        }
    }

    static final class LongTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("number");
        }
    }

    static final class ShortTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("number");
        }
    }

    static final class VoidTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("null");
        }
    }

    static final class StringTypeAdapter extends DefaultTypeAdapter {
        public TypeDefinition toJsonType(Type type) {
            return new TypeDefinition("string");
        }
    }
}
